/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.base.common.util;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URL;

@Slf4j
public class HttpContextUtils {

    private static String env;

    private static String applicationName;

    //TODO threadLocal保存HttpContext
    private static ThreadLocal<HttpServletRequest> threadLocalRequest = new ThreadLocal<>();

    //用于处理异步任务时获取请求域
    public static void setThreadLocalRequest(HttpServletRequest request) {
        threadLocalRequest.set(request);//当前线程
    }

    public static void clearThreadLocalRequest() {
        threadLocalRequest.remove();//当前线程
    }


    public static void setRequestAttribute(String key, String value) {
        HttpServletRequest request = getHttpServletRequest();
        if (request != null){
            request.setAttribute(key, value);
        }
    }

    public static Object getRequestAttribute(String key) {
        HttpServletRequest request = getHttpServletRequest();
        Object value = request.getAttribute(key);
        return value;
    }


    public static String getIpAddr() {
        return getIpAddr(getHttpServletRequest());
    }

    /**
     * 获取IP地址
     * <p>
     * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，X-Forwarded-For中第一个非unknown的有效IP字符串，则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        if (request == null) {
            return "";
        }
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }

            if (StringUtils.isBlank(ip)){
                return "";
            }

            if (ip.indexOf(".") < 0) {
                return null;
            }

            if (StringUtils.isNotBlank(ip)) {
                if (ip.indexOf(",") > -1) {
                    ip = ip.replaceAll("\\s+", " ").trim();
                    String[] ips = ip.split(",");
                    return ips[0];
                } else {
                    return ip;
                }
            }
        } catch (Exception e) {
            log.error("IPUtils ERROR ", e);
        }

        return ip;
    }

    public static HttpServletRequest getHttpServletRequest() {
        HttpServletRequest threadRequest = threadLocalRequest.get();
        if (threadRequest != null) {
            return threadRequest;
        }
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return ((ServletRequestAttributes) requestAttributes).getRequest();
        }
        //TODO 测试用
        return null;
    }


    public static HttpServletResponse getHttpServletResponse() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return ((ServletRequestAttributes) requestAttributes).getResponse();
        }
        return null;
    }


    public static String getDomain() {
        HttpServletRequest request = getHttpServletRequest();
        StringBuffer url = request.getRequestURL();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
    }

    public static String getOrigin() {
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader("Origin");
    }

    public static String getReferer() {
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader("Referer");
    }



    public static String getOriginSchemeHost() {
        HttpServletRequest request = getHttpServletRequest();
        return getOriginSchemeHost(request);
    }

    public static String getOriginSchemeHost(HttpServletRequest request) {
        try {
            String requestURL = request.getRequestURL().toString();
            URL url = new URL(requestURL);
            //获取请求协议
            String requestScheme = url.getProtocol();
            String requestHost = url.getHost();
            int port = url.getPort();
            if (port != -1) {
                return requestScheme + "://" + requestHost + ":" + port;
            }
            return requestScheme + "://" + requestHost;
        } catch (MalformedURLException e) {
            return null;
        }
    }

    public static String getOriginUrl() {
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        return getOriginUrl(request);
    }

    public static String getOriginUrl(HttpServletRequest request) {
        return getOriginSchemeHost() + request.getRequestURI();
    }


    public static void clearRequestAttribute(String key) {
        getHttpServletRequest().setAttribute(key,null);
    }
}
